import axios from "@/request/http.js";
const directApi = "/f_api/download/direct";
const rangeApi = "/f_api/download/rangeFile";
// buffer 合并 https://stackoverflow.com/questions/39502374/javascript-combine-arraybuffer-parts
// https://louiswt.github.io/2019/06/10/browser-binary/
function downloadRange(url, start, end, i, token) {
  return new Promise((resolve, reject) => {
    const req = new XMLHttpRequest();
    req.open("GET", url, true);
    req.setRequestHeader("Authorization", "Bearer " + token);
    req.setRequestHeader("range", `bytes=${start}-${end}`);
    req.responseType = "blob";
    req.onload = function(oEvent) {
      req.response.arrayBuffer().then((res) => {
        resolve({
          i,
          buffer: res,
        });
      });
    };
    req.send();
  });
}
// 合并buffer
function concatenate(resultConstructor, arrays) {
  let totalLength = 0;
  for (let arr of arrays) {
    totalLength += arr.length;
  }
  let result = new resultConstructor(totalLength);
  let offset = 0;
  for (let arr of arrays) {
    result.set(arr, offset);
    offset += arr.length;
  }
  return result;
}
function directDownload(fileUrl, file, token, notify) {
  const fileName = file.fileName;
  const url =
    directApi + "?fileUrl=" + fileUrl + "&fileName=" + fileName || "未命名文件";
  // console.time("直接下载", url);
  const req = new XMLHttpRequest();
  req.open("GET", url, true);
  req.responseType = "blob";
  req.setRequestHeader("Authorization", "Bearer " + token);
  // 监听下载进度
  req.onprogress = (event) => {
    if (event.lengthComputable) {
      const p = (event.loaded / event.total) * 100;
      notify.message = `进度${Math.floor(p)}%`;
      if (p === 100) {
        notify.close();
      }
    }
  };
  req.onload = function(oEvent) {
    if (oEvent.currentTarget.status === 200) {
      const content = req.response;
      const aTag = document.createElement("a");
      aTag.download = fileName;
      const blob = new Blob([content]);
      const blobUrl = URL.createObjectURL(blob);
      aTag.href = blobUrl;
      aTag.click();
      URL.revokeObjectURL(blob);
      console.timeEnd("直接下载");
    } else {
      notify.close();
      throw Error("接口异常");
    }
  };
  req.send();
}

function rangeDownload(fileUrl, file, token, notify) {
  const url = rangeApi + "?fileUrl=" + fileUrl;
  const fileName = file.fileName;
  let m = 31457280;
  const size = file.size;
  // 跳入直接下载不走分片，分片有问题
  if (fileUrl) {
    // if (!size || size <= m) {
    //直接下载
    directDownload(fileUrl, file, token, notify);
  } else {
    const length = parseInt(size / m);
    // debugger
    const arr = [];
    for (let i = 0; i <= length; i++) {
      let start = i * m;
      let end = i == length ? size - 1 : (i + 1) * m - 1;
      arr.push(downloadRange(url, start, end, i, token));
    }
    // console.log(arr);
    Promise.all(arr).then((res) => {
      // console.time('合并数据');
      const arrBufferList = res
        .sort((item) => item.i - item.i)
        .map((item) => new Uint8Array(item.buffer));
      const allBuffer = concatenate(Uint8Array, arrBufferList);
      console.log(allBuffer);
      const blob = new Blob([allBuffer]); //, { type: 'image/jpeg' }
      console.log(blob);
      const blobUrl = URL.createObjectURL(blob);
      const aTag = document.createElement("a");
      aTag.download = fileName;
      aTag.href = blobUrl;
      aTag.click();
      URL.revokeObjectURL(blob);
      console.timeEnd("合并数据");
      console.timeEnd("分片下载");
    });
  }
}

function download(url, fileName) {
  let self = this;
  let x = new XMLHttpRequest();
  x.open("GET", url, true);
  x.responseType = "blob";
  x.onload = function() {
    //self.exportLoading = false;
    let url = window.URL.createObjectURL(x.response);
    let a = document.createElement("a");
    a.href = url;
    a.download = fileName;
    a.click();
  };
  x.send();
}

export { directDownload, rangeDownload, download };
